package me.demo.base;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import me.boot.common.context.ContextUtil;
import me.boot.common.data.model.TenantInfo;
import me.boot.db.mybatis.datasource.DynamicDataSourceService;
import me.demo.base.entity.SysTenant;
import me.demo.base.service.SysTenantService;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Slf4j
@Component
public class DomainHandlerInterceptor implements HandlerInterceptor {

    @Value("${sysDomain:sys.me}")
    private String sysDomain;

    @Lazy
    @Autowired
    DynamicDataSourceService dynamicDataSourceService;

    @Autowired
    SysTenantService tenantService;

    List<SysTenant> tenants = Lists.newArrayList();

    @PostConstruct
    public void init() {
        log.info("Init DomainInterceptor");

        tenants.addAll(tenantService.list());
        log.debug("租户数量: {}", tenants.size());
        tenants.forEach(tenant -> log.debug("{}", tenant));
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (isMasterDomain(request)) {
            return true;
        }

        String subDomain = getSubDomain(request);
        if (StrUtil.isNotEmpty(subDomain)) {
            SysTenant tenant = getTenant(subDomain);
            if (tenant != null) {
                //记录当前线程的租户
                ContextUtil.setTenant(new TenantInfo(tenant.getId(), tenant.getName()));
                log.debug("request from tenant => {}", tenant);
                return true;
            } else {
                log.debug("无效的租户子域名：{}", subDomain);
            }
        }
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        ContextUtil.setTenant(null);
    }

    boolean isMasterDomain(HttpServletRequest request) {
        String serverName = request.getServerName();
        return StrUtil.equalsAnyIgnoreCase(serverName, sysDomain, "localhost", "127.0.0.1");
    }

    String getSubDomain(HttpServletRequest request) {
        String serverName = request.getServerName();
        String suffix = "." + sysDomain;
        if (serverName.endsWith(suffix)) {
            //截取子域名
            return StrUtil.subBefore(serverName, suffix, true);
        }
        return null;
    }

    SysTenant getTenant(String subDomain) {
        return tenants.stream()
                .filter(tenant -> StrUtil.equalsIgnoreCase(tenant.getSubDomain(), subDomain))
                .findFirst().orElse(null);
    }

}
